﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 *
 **/
using System;
using System.Collections.ObjectModel;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using Peter.Common;
using Peter.Common.MainMenu;
using Peter.Data;

namespace Peter.Logic
{
   /// <summary>
   /// A model for exploring a zip file.
   /// TODO: Support gzip, tar, bzip2 (bz2), 7 zip...
   /// </summary>
   public sealed class ModelZipExplorer : PeterDocument
   {
      private readonly ObservableCollection<ModelZipItem> m_ZipItems;
      private bool m_IsReadOnly;

      /// <summary>
      /// Initializes a new zip file explorer.
      /// </summary>
      /// <param name="zipFile">Zip file to explore.</param>
      public ModelZipExplorer (FileInfo zipFile)
      {
         this.FileInfo = zipFile;
         this.Title = zipFile.Name;
         this.ToolTip = zipFile.FullName;
         this.IsReadOnly = zipFile.IsReadOnly;
         this.Icon = MainMenuIcon.Zip;
         this.m_ZipItems = new ObservableCollection<ModelZipItem> ();
         this.ContentId = string.Format ("{0}|{1}", Guids.ZIP_EXPLORER, zipFile.FullName);

         Action <FileInfo> loadZip = this.LoadZipFile;
         loadZip.BeginInvoke (this.FileInfo, null, null);
      }

      /// <summary>
      /// Gets the list of zip entries in the zip file.
      /// </summary>
      public ObservableCollection<ModelZipItem> ZipItems { get { return this.m_ZipItems; } }

      /// <summary>
      /// Gets the text of the document.
      /// </summary>
      public override string Text
      {
         get { return string.Empty; }
      }

      /// <summary>
      /// Gets or Sets if the file is read only or not.
      /// </summary>
      public bool IsReadOnly
      {
         get { return m_IsReadOnly; }
         set
         {
            this.m_IsReadOnly = value;
            this.RaisePropertyChanged ("IsReadOnly");
         }
      }

         /// <summary>
      /// Thread safe method for loading the zip file.
      /// </summary>
      /// <param name="file"></param>
      private void LoadZipFile (FileInfo file)
      {
         using (var zipFile = new ZipFile (file.FullName))
         {
            foreach (ZipEntry zipEntry in zipFile)
            {
               if (zipEntry.IsFile)
               {
                  var entry = zipEntry;
                  this.GuiDispatcher.BeginInvoke (
                     new Action <ZipEntry> (e => this.ZipItems.Add (new ModelZipItem (e))), entry);
               }
            }
         }
      }
   }
}
